package cn.kgc.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.kgc.api.entity.Menus;
import cn.kgc.api.entity.RolesMenus;
import cn.kgc.api.mapper.MenusMapper;
import cn.kgc.api.mapper.RolesMenusMapper;
import cn.kgc.api.service.MenusService;
import cn.kgc.api.util.SystemUtil;
import cn.kgc.common.constant.SystemConstant;
import cn.kgc.api.vo.MetaVo;
import cn.kgc.api.vo.RouterVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author kgc
 */
@Slf4j
@Service("menusService")
public class MenusServiceImpl extends ServiceImpl<MenusMapper, Menus> implements MenusService {

    @Resource
    private RolesMenusMapper rolesMenusMapper;

    @Resource
    private MenusMapper menusMapper;

    @Override
    public List<Menus> getAllMenus(Map<String,String> params) {
        LambdaQueryWrapper<Menus> lambdaQueryWrapper=new LambdaQueryWrapper<>();

        lambdaQueryWrapper.likeRight(StrUtil.isNotBlank(params.get("menuName")),
               Menus::getMenuName, params.get("menuName") );

        lambdaQueryWrapper.likeRight(StrUtil.isNotBlank(params.get("menuCode")),
                Menus::getMenuCode, params.get("menuCode") );

        List<Menus> menus = menusMapper.selectList(lambdaQueryWrapper);
        //如果是查询所有
        if(StrUtil.isBlank(params.get("menuName")) && StrUtil.isBlank(params.get("menuCode"))){
            return SystemUtil.tree(menus);
        }
        //如果不是直接将查询结果返回
        return menus;
    }

    @Override
    public List<String> getButtonPerms() {
        List<Menus> menus = getRoleMenus(SystemUtil.getLoginUsers().getRoleId());
        List<String> buttonPerms = new ArrayList<>();
        for (Menus menu : menus) {
            if(menu.getMenuType().equals(SystemConstant.MenuType.BUTTON_MENU.getCode())){
                buttonPerms.add(menu.getPerm());
            }
        }
        return buttonPerms;
    }

    /**
     * 获得菜单路由信息
     */
    @Override
    public List<RouterVo> getAllRouters() {
        //获得所有菜单信息
        List<Menus> menus = getRoleMenus(SystemUtil.getLoginUsers().getRoleId());
        //将菜单信息树化
        List<Menus> tree = SystemUtil.tree(menus);
        //将树化后的菜单转为路由类型集合
        return builderRouterVO(tree);
    }


    private static List<RouterVo> builderRouterVO(List<Menus> treeMenuList) {
        List<RouterVo> routerVOList=new ArrayList<>();
        //遍历每个菜单,每个菜单对应一个路由地址
        for (Menus sysMenu : treeMenuList) {
            //路由信息
            RouterVo routerVO=new RouterVo();
            routerVO.setPath(sysMenu.getPath());
            routerVO.setComponent(sysMenu.getComponent());
            routerVO.setName(sysMenu.getMenuName());
            routerVO.setRedirect(sysMenu.getRedirect());
            routerVO.setId(sysMenu.getId());
            routerVO.setIcon(sysMenu.getIcon());
            MetaVo meta=new MetaVo();
            meta.setTitle(sysMenu.getMenuName());
            routerVO.setMeta(meta);
            //如果当前的菜单是按钮,并且按钮是有路由组件的
            if(sysMenu.getMenuType()== SystemConstant.MenuType.BUTTON_MENU.getCode()){
                if(StrUtil.isNotEmpty(sysMenu.getComponent())){
                    routerVO.setHide(true);
                }else {
                    //如果按钮路由组件为空,不需要将此按钮的信息放入到路由中
                    continue;
                }
            }
            //菜单下有子菜单信息,将子菜单信息转为路由信息
            List<Menus> children = sysMenu.getChildren();
            if(CollUtil.isNotEmpty(children)){
                List<RouterVo> childrenRouterVo= builderRouterVO(children);
                routerVO.setChildren(childrenRouterVo);
            }
            routerVOList.add(routerVO);
        }
        return routerVOList;
    }

    @Override
    public int count(int parentId, String menuName) {
        LambdaQueryWrapper<Menus> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Menus::getParentId,parentId);
        lambdaQueryWrapper.eq(StrUtil.isNotBlank(menuName),Menus::getMenuName,menuName);
        return menusMapper.selectCount(lambdaQueryWrapper);
    }

    @Override
    public List<Menus> getRoleMenus(int roleId) {
        //根据角色id查询角色菜单的对应信息
        LambdaQueryWrapper<RolesMenus> queryWrapper1=new LambdaQueryWrapper<>();
        queryWrapper1.eq(RolesMenus::getRid,roleId);
        List<RolesMenus> rolesMenus = rolesMenusMapper.selectList(queryWrapper1);
        //根据角色id查询到的角色菜单的对应信息为空,说明此角色没有分配菜单
        if(CollUtil.isEmpty(rolesMenus)){
            //返回空菜单
            return ListUtil.empty();
        }
        //获得角色所拥有的菜单的ID
        List<Integer> menusId= rolesMenus.stream().map(RolesMenus::getMid)
                .collect(Collectors.toList());
        //根据菜单id查询菜单信息
        return menusMapper.selectBatchIds(menusId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateRoleMenu(Map<String, Object> params) {
        //获得传入的角色Id
        Integer roleId = MapUtil.getInt(params, "roleId");
        //获得传入的菜单Id集合
        List<Integer> menusId = (List<Integer>)MapUtil.get(params, "menusId", List.class);
        //根据roleId删除原有的角色菜单信息
        LambdaQueryWrapper<RolesMenus> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(RolesMenus::getRid,roleId);
        rolesMenusMapper.delete(queryWrapper);
        //插入新的角色菜单信息
        for (int menuId: menusId) {
            RolesMenus rolesMenus=new RolesMenus();
            rolesMenus.setRid(roleId);
            rolesMenus.setMid(menuId);
            rolesMenusMapper.insert(rolesMenus);
        }
        return true;
    }
}